<script>
import classNames from 'classnames'
import { ConfigConsumerProps } from '../config-provider'
import { emptyCellText } from '@/env'

const TABLE_METHODS = [
  'clearSelection',
  'toggleRowSelection',
  'toggleAllSelection',
  'toggleRowExpansion',
  'setCurrentRow',
  'clearSort',
  'doLayout',
  'sort'
]

const TABLE_EVENTS = [
  'select',
  'select-all',
  'selection-change',
  'row-click',
  'cell-click'
]

const PAGER_EVENTS = [
  'size-change',
  'current-change',
  'prev-click',
  'next-click'
]

const DEFAULT_PAGINATION_CONFIG = {
  layout: 'prev, pager, next, total, jumper',
  'page-size': 10,
  'page-sizes': [10, 20, 50, 100]
}

const camelCase = name =>
  name.replace(/([:\-_]+(.))/g, (_, separator, letter, offset) =>
    offset ? letter.toUpperCase() : letter
  )

export default {
  inheritAttrs: false,
  name: 'VTable',
  componentName: 'VTable',
  inject: {
    configProvider: { default: () => ConfigConsumerProps }
  },
  props: {
    dataSource: {
      type: Array,
      default () {
        return []
      }
    },
    columns: {
      type: Array,
      default () {
        return []
      }
    },
    height: [String, Number],
    maxHeight: [String, Number],
    stripe: Boolean,
    border: {
      type: Boolean,
      default: false
    },
    size: {
      type: String,
      validator: val => ['medium', 'small', 'mini'].indexOf(val) > -1
    },
    // 分页相关
    pagination: {
      type: [Object, Boolean],
      default () {
        return DEFAULT_PAGINATION_CONFIG
      }
    },
    // 自定义
    loading: Boolean,
    align: {
      type: String,
      default: 'center'
    },
    emptyCellText: {
      type: String,
      default: emptyCellText
    },
    sizeChange: Function,
    currentChange: Function,
    currentPage: Number,
    total: Number,
    showOverflowTooltip: Boolean
  },
  methods: {
    delegateMethods () {
      TABLE_METHODS.forEach(method => {
        this[method] = () => this.$refs.table[method].apply(null, arguments)
      })
    },
    getElTable () {
      return this.$refs.table
    }
  },
  render () {
    const { columns, dataSource, showOverflowTooltip, $attrs } = this
    const tableColumns = []

    const getPrefixCls = this.configProvider.getPrefixCls

    const prefixCls = getPrefixCls('table')
    const pagerCls = getPrefixCls('pager')

    const tableClass = classNames(prefixCls, {
      [`${prefixCls}--${this.size}`]: this.size
    })
    const wrapperClass = classNames(`${prefixCls}-wrapper`)
    const toolbarClass = classNames(`${prefixCls}__toolbar`)

    let data
    columns.forEach((col, index) => {
      let { align, ...props } = col

      // 处理无数据展示
      let originalFormatter =
        col.formatter ||
        ((row, column, cellValue, index) => {
          if (
            cellValue === null ||
            cellValue === '' ||
            cellValue === undefined
          ) {
            cellValue = this.emptyCellText
          }
          return <span>{cellValue}</span>
        })

      let formatter = function (...args) {
        let ret = originalFormatter.call(this, ...args)
        return ret
      }

      props = {
        ...props,
        formatter,
        align: align || this.align,
        // 操作列(无prop属性)默认不tooltip
        showOverflowTooltip: !props.prop
          ? false
          : col.showOverflowTooltip !== undefined
            ? col.showOverflowTooltip
            : showOverflowTooltip
      }
      data = { props }
      tableColumns.push(<el-table-column {...data} />)
    })
    // 表格props
    data = {
      props: this.$props,
      on: (function (self) {
        const events = {}
        TABLE_EVENTS.forEach(ev => {
          events[ev] = function () {
            const args = [].slice.call(arguments)
            args.unshift(ev)
            self.$emit(...args)
          }
        })
        return events
      })(this)
    }
    const hasPager = this.$props.pagination !== false
    let Pager = null
    if (hasPager) {
      const pagerData = {
        props: Object.assign(
          {
            'current-page': this.currentPage,
            total: this.total
          },
          DEFAULT_PAGINATION_CONFIG,
          this.$props.pagination
        ),
        on: (function (self) {
          const events = {
            'update:currentPage': val => {
              self.$emit('update:currentPage', val)
            }
          }
          PAGER_EVENTS.forEach(ev => {
            events[ev] = function () {
              const args = [].slice.call(arguments)
              args.unshift(ev)
              self.$emit(...args)
              const fn = camelCase(ev)
              if (typeof self[fn] === 'function') {
                // 作为传递时去掉事件名提供参数
                self[fn](...args.slice(1))
              }
            }
          })
          return events
        })(this)
      }

      Pager = <el-pagination {...pagerData} ref="pager" />
    }

    const toolbar =
      this.$slots.toolbar ||
      (typeof this.renderToolbar === 'function' && this.renderToolbar())

    const tableProps = {
      attrs: {
        ...$attrs
      }
    }
    return (
      <div class={wrapperClass} v-loading={this.loading}>
        {toolbar && <div class={toolbarClass}>{toolbar}</div>}
        <el-table
          ref="table"
          class={tableClass}
          data={dataSource}
          {...data}
          {...tableProps}
        >
          <v-empty slot="empty" />
          {tableColumns}
        </el-table>
        {Pager && <div class={pagerCls}>{Pager}</div>}
      </div>
    )
  },
  mounted () {
    this.delegateMethods()
  }
}
</script>
